<template>
  <BasicModal
    v-bind="$attrs"
    @register="register"
    :title="displayModuleTitle"
    :footer="null"
    width="1100px"
    centered
    :body-style="{ maxHeight: '700px' }"
    @cancel="opSuccess"
  >
    <a-form
      ref="formRef"
      :model="hazardBasicInfo"
      :label-col="{ style: 'width: 90px' }"
      style="margin-top: 20px"
    >
      <a-row>
        <a-col :span="8">
          <a-form-item name="ismajor" style="margin-left: 90px" :rules="[{ required: true }]"
            ><a-radio-group
              v-model:value="hazardBasicInfo.ismajor"
              disabled
              class="ismajorButton"
              @change="
                (e) => {
                  // 当危险源是否为重大状态更改时,要修改默认的风险等级
                  setEvaluationValue({
                    risklevel: e.target.value
                      ? riskLevelOptions[riskLevelOptions.length - 1].value
                      : riskLevelOptions[0].value,
                  });
                  let op = methodList.find(
                    (item) => item.method == getFieldsValue().method,
                  ).options;
                  let tmp = {};
                  op.forEach((element) => {
                    tmp[element.name] = Number(
                      hazardBasicInfo.ismajor
                        ? element.options[element.options.length - 1].key
                        : element.options[0].key,
                    );
                  });
                  riskValueField = tmp;
                }
              "
            >
              <a-radio-button :value="false">一般危险源</a-radio-button>
              <a-radio-button :value="true">重大危险源</a-radio-button>
            </a-radio-group>
          </a-form-item></a-col
        >
        <a-col :span="7">
          <a-form-item label="类别" name="categoryname" :rules="[{ required: true }]"
            ><a-input v-model:value="hazardBasicInfo.categoryname" disabled />
          </a-form-item>
        </a-col>
        <a-col :span="7">
          <a-form-item label="项目" name="projectname" :rules="[{ required: true }]"
            ><a-input v-model:value="hazardBasicInfo.projectname" disabled />
          </a-form-item>
        </a-col>
        <a-col :span="11"
          ><a-form-item label="危险源" name="hazardname" :rules="[{ required: true }]"
            ><a-input v-model:value="hazardBasicInfo.hazardname" disabled />
          </a-form-item>
        </a-col>
        <a-col :span="11"
          ><a-form-item label="具体单元" name="unitname"
            ><a-input v-model:value="hazardBasicInfo.unitname" disabled />
          </a-form-item>
        </a-col>
        <a-col :span="22"
          ><a-form-item label="事故诱因" name="couse"
            ><a-input v-model:value="hazardBasicInfo.couse" disabled />
          </a-form-item>
        </a-col>
      </a-row>
    </a-form>
    <a-divider>风险评价操作</a-divider>
    <BasicForm @register="registerEvaluationForm">
      <template #method="{ model, field }">
        <a-radio-group
          v-model:value="model[field]"
          :options="methodOption"
          @change="
            (e) => {
              // 先赋空消除无用字段,并把当前风险值重置为低风险
              riskValueField = {};
              model['risklevel'] = hazardBasicInfo.ismajor
                ? riskLevelOptions[riskLevelOptions.length - 1].value
                : riskLevelOptions[0].value;
              // 当评价方法变化时,对应的方法需要字段也变化了(如LS方法变成LEC方法时,字段由L/S变成L/E/C),且字段对应的默认值同时也变化了
              // 这里需要重新赋值不同评价方法下的默认值
              // 先通过find找到所选评价方法的字段配置数组
              let op = methodList.find((item) => item.method == e.target.value).options;
              //在这里如果是直接法(无字段),那么op就为[],那么下面给riskValueField赋的值还是{},不会造成影响
              //那么这个时候请求不会携带除了方法外的字段,符合当前的需求
              let tmp = {};
              // 再通过forEach取得每个字段配置中的最小值当作默认值
              // element.name为字段名,如:L,S,E,C
              // 如果当前危险源为一般危险源,就默认所有初始值为最低,风险等级为低风险,如果为重大危险源,默认初始值最高,风险等级为重大风险
              op.forEach((element) => {
                tmp[element.name] = Number(
                  hazardBasicInfo.ismajor
                    ? element.options[element.options.length - 1].key
                    : element.options[0].key,
                );
              });
              riskValueField = tmp;
            }
          "
        />
      </template>
      <template #riskValue="{ model, field }">
        <!-- 通过请求获取的评价方法数组及其方法下的字段配置,for循环自动生成字段对应的Slider -->
        <!-- 便于之后增加评价方法时,自动生成评价所需字段 -->
        <a-form-item-rest>
          <!-- filter找到当前所选评价方法对应的方法字段,只渲染当前选择方法所需的字段(如:LS评价法只需要L/S) -->
          <a-row
            v-if="model['method'] !== 1"
            v-for="item in methodList.filter((item) => {
              return item.method == model['method'];
            })[0].options"
            style="margin-bottom: 10px"
          >
            <!-- min,max,step都需要Number类型 -->
            <a-col :span="2">
              <a-tooltip>
                <template #title>{{ item.prompt }}</template
                ><div style="text-align: center; line-height: 32px"
                  ><ExclamationCircleOutlined style="color: #a4a4a4; margin: 0 5px" />{{
                    item.name
                  }}</div
                >
              </a-tooltip>
            </a-col>
            <a-col :span="18">
              <a-slider
                v-model:value="riskValueField[item.name]"
                :max="Number(item.options[item.options.length - 1].key)"
                :min="Number(item.options[0].key)"
                :step="Number(item.options[0].key)"
                :tip-formatter="(value) => sliderTipFormatter(value, item.options)"
                :marks="returnMarks(item)"
                @change="
                  (e) => {
                    // 由于riskValueField里的字段,只会有当前出现的字段,所以只需要把它含有的所有字段值相乘就可以得出风险总值,无需判断是哪个字段值改变了
                    //(如: LS评价法中riskValueField只会出现L/S字段,因为在method改变绑定的change方法中
                    // 每次都先给riskValueField赋空{},消除无用的字段, 再新赋上当前选择评价方法含有字段与其默认值)
                    //在这里不用判断是不是直接法,直接法options为空,无生成slider,不触发这个方法
                    let levelSumValue = Object.values(riskValueField).reduce((a, b) => a * b);
                    //获取到当前选择的方法,风险等级阀值在方法对象中
                    let currenMethod = methodList.filter((item) => {
                      return item.method == model['method'];
                    })[0];
                    if (levelSumValue >= currenMethod.level4) model['risklevel'] = 4;
                    else if (levelSumValue >= currenMethod.level3) model['risklevel'] = 3;
                    else if (levelSumValue >= currenMethod.level2) model['risklevel'] = 2;
                    else model['risklevel'] = 1;
                  }
                "
              />
            </a-col>
            <a-col :span="2"
              ><div style="text-align: center; line-height: 32px">{{
                riskValueField[item.name]
              }}</div></a-col
            >
          </a-row>
        </a-form-item-rest>
      </template>
      <template #risklevel="{ model, field }">
        <a-radio-group
          v-model:value="model[field]"
          :disabled="model['method'] == 1 ? false : true"
          button-style="solid"
          class="riskButton"
        >
          <a-radio-button v-for="(item, index) in riskLevelOptions" :value="item.value">{{
            item.label +
            (model['method'] !== 1
              ? '(≥' +
                methodList.filter((item) => {
                  return item.method == model['method'];
                })[0][`level${index + 1}`] +
                ')'
              : '')
          }}</a-radio-button>
        </a-radio-group>
        <!-- 根据评价方法不同计算风险总值的方法也不同 -->
        <span v-if="model['method'] !== 1 && Object.values(riskValueField).length > 0"
          >&ensp;风险值:{{
            Object.values(riskValueField)
              .reduce((a, b) => a * b)
              .toFixed(2)
          }}</span
        >
        <div> </div>
      </template>
    </BasicForm>
    <div class="steps-action">
      <!-- <a-button v-if="currentIndex" @click="switchHazard('pre')"
        ><LeftOutlined />上一个危险源</a-button
      > -->
      <a-button type="primary" size="medium" @click="validateForm()"> 评价 </a-button>
      <a-button size="medium" @click="opSuccess"> 关闭 </a-button>
      <!-- <a-button v-if="currentIndex" @click="switchHazard('next')"
        >下一个危险源<RightOutlined
      /></a-button> -->
    </div>
  </BasicModal>
</template>
<script lang="ts">
  import { computed, defineComponent, onMounted, ref, unref, watch } from 'vue';
  import { BasicModal, useModalInner } from '/@/components/Modal';
  import { useUserStore } from '/@/store/modules/user';
  import { BasicForm, useForm } from '/@/components/Form/index';
  import { displayTitle } from '/@/utils/QcUnifyUtil';
  import { QcUnifyTransToChildProps } from '/#/QcUnify';
  import { useMessage } from '/@/hooks/web/useMessage';
  import {
    getOneHazardInfo,
    evaluationHazard,
    getIdentifyMethod,
    getLatestEvaluationRecord,
  } from '/@/api/ehs/hazard';
  import { ExclamationCircleOutlined, LeftOutlined, RightOutlined } from '@ant-design/icons-vue';
  import { riskEvaluationFormSchema } from './hazard.data';
  import { queryEnumOptions } from '/@/api/platform/enum';
  import type { FormInstance } from 'ant-design-vue';
  const { createMessage } = useMessage();
  export default defineComponent({
    components: { BasicModal, BasicForm, ExclamationCircleOutlined, LeftOutlined, RightOutlined },
    name: 'HazardEvaluateModal',
    setup(props, { emit }) {
      const formRef = ref<FormInstance>();
      const riskLevelOptions = ref(); // 风险等级枚举
      const qcUnifyProps = ref<QcUnifyTransToChildProps>();
      const dataId = ref();
      const hazardBasicInfo = ref({
        unitid: '',
        unitname: '',
        categoryname: '',
        categorycode: '',
        projectname: '',
        projectcode: '',
        hazardname: '',
        hazardid: '',
        itemname: '',
        itemcode: '',
        ismajor: false,
        couse: '',
      });
      const userStore = useUserStore();
      const { realName = '', avatar, desc } = userStore.getUserInfo || {};
      const riskValueField = ref({}); // 用来存储表单填写的L/S/E/C字段值
      const methodList = ref([]); // 评价方法列表(所有的评价方法和它的字段以及阀值)
      const methodOption = ref([]); // 表单method域选择配置项(只有method配置项,label,value)
      const currentIndex = ref(); // 现在操作的数组索引
      const hazardList = ref([]); // 要操作的危险源清单数组
      const [register, { closeModal, changeLoading }] = useModalInner((data) => {
        dataId.value = null;
        if (data != undefined && data != null) {
          let unrefData = unref(data);
          qcUnifyProps.value = unrefData;
          //接收父组件传递的数据
          dataId.value = unrefData.dataId;
          currentIndex.value = data.index;
          hazardList.value = data.hazardList;
          if (dataId.value) {
            getOneHazardInfo(dataId.value).then((res) => {
              getLatestEvaluationRecord(dataId.value).then((res2) => {
                // 有的数据有记录,有的数据可能为null,要区分判断一下
                hazardBasicInfo.value = res;
                setEvaluationValue({
                  risklevel: hazardBasicInfo.value.ismajor
                    ? riskLevelOptions.value[riskLevelOptions.value.length - 1].value
                    : riskLevelOptions.value[0].value,
                  byuser: realName,
                });
                //将附件的字符串json对象化
                if (res2) {
                  res2.attachment = res2 && res2.attachment ? JSON.parse(res2.attachment) : [];
                  // 过滤为空字段赋值
                  let param2 = res2
                    ? Object.keys(res2)
                        .filter((key) => res2[key] !== null)
                        .reduce((acc, key) => ({ ...acc, [key]: res2[key] }), {})
                    : {};
                  console.log(param2, 'param');
                  setEvaluationValue(param2);
                  riskValueField.value = res2 && res2.content ? JSON.parse(res2.content) : {};
                }
              });
            });
          }
        }
      });
      const [
        registerEvaluationForm,
        {
          setFieldsValue: setEvaluationValue,
          validate: validateEvaluation,
          updateSchema: updateEvaluationSchema,
          resetFields: resetEvaluation,
          getFieldsValue,
        },
      ] = useForm({
        labelWidth: 80,
        schemas: riskEvaluationFormSchema,
        showActionButtonGroup: false,
        scrollToFirstError: true,
      });

      let displayModuleTitle = computed(() => {
        return displayTitle(qcUnifyProps.value);
      });
      async function validateForm() {
        // 提交风险评价表单
        const values = await validateEvaluation();
        formRef.value.validate().then(() => {
          let param;
          let fileIds = '';
          if (values.attachment && values.attachment.length > 0x0) {
            //将json对象转换为字符串
            fileIds = JSON.stringify(values.attachment);
            //   values.files.forEach((element) => {
            //     fileIds += element.id + ',';
            //   });
          }
          values.attachment = fileIds;
          if (values.method == 1) {
            param = {
              ...values,
              hazardid: dataId.value,
              unitid: hazardBasicInfo.value.unitid,
              unitname: hazardBasicInfo.value.unitname,
              hazardname: hazardBasicInfo.value.hazardname,
            };
          } else {
            param = {
              ...values,
              hazardid: dataId.value,
              content: JSON.stringify(riskValueField.value),
              unitid: hazardBasicInfo.value.unitid,
              unitname: hazardBasicInfo.value.unitname,
              hazardname: hazardBasicInfo.value.hazardname,
            };
          }
          changeLoading(true);
          evaluationHazard({
            ...param,
          }).then((res) => {
            if (res == null) {
              createMessage.success('风险评价成功');
              changeLoading(false);
              opSuccess();
            }
          });
        });
        console.log(dataId.value, 'dataId');
      }
      function opSuccess() {
        formRef.value.resetFields();
        resetEvaluation();
        emit('success');
        closeModal();
      }
      // function switchHazard(op) {
      //   if (op == 'pre') {
      //     // 点击上一个危险源按钮
      //     if (currentIndex.value == 0)
      //       return createMessage.error('此危险源为第一个,无上一个危险源');
      //     else currentIndex.value = currentIndex.value - 1;
      //   } else {
      //     // 点击下一个危险源按钮
      //     if (currentIndex.value + 1 == hazardList.value.length)
      //       return createMessage.error('此危险源为最后一个,无下一个危险源');
      //     else currentIndex.value = currentIndex.value + 1;
      //   }
      //   // 更新弹窗title以及dataId
      //   qcUnifyProps.value.operateString = `(当前操作第${currentIndex.value + 1}个,共${
      //     hazardList.value.length
      //   }个)`;
      //   dataId.value = hazardList.value[currentIndex.value].hazardid;
      //   resetEvaluation();
      //   // 获取新的危险源信息
      //   getOneHazardInfo(dataId.value).then((res) => {
      //     getLatestEvaluationRecord(dataId.value).then((res2) => {
      //       // 有的数据有记录,有的数据可能为null,要区分判断一下
      //       hazardBasicInfo.value = res;
      //       //将附件的字符串json对象化
      //       res2.attachment = res2 && res2.attachment ? JSON.parse(res2.attachment) : [];
      //       setEvaluationValue({
      //         risklevel: hazardBasicInfo.value.ismajor
      //           ? riskLevelOptions.value[riskLevelOptions.value.length - 1].value
      //           : riskLevelOptions.value[0].value,
      //       });
      //       // 过滤为空字段赋值
      //       let param2 = res2
      //         ? Object.keys(res2)
      //             .filter((key) => res2[key] !== null)
      //             .reduce((acc, key) => ({ ...acc, [key]: res2[key] }), {})
      //         : {};
      //       setEvaluationValue(param2);
      //       riskValueField.value = res2 && res2.content ? JSON.parse(res2.content) : {};
      //     });
      //   });
      // }
      // 返回slider的悬浮文字,从大到小依次判断属于哪个区间,返回区间对应的危险程度文字
      function sliderTipFormatter(value, options) {
        // 这里传进来的options是字段对应的配置的各个阀值,是接口传回来的值,之后需要更改阀值数据只需要更改数据库即可
        for (let i = options.length - 1; i >= 0; i--) {
          if (value >= Number(options[i].key)) return options[i].value;
        }
      }
      // 返回slider刻度标记
      function returnMarks(item) {
        let tmp = {};
        tmp[item.options[item.options.length - 1].key] = item.options[item.options.length - 1].key;
        tmp[item.options[0].key] = item.options[0].key;
        return tmp;
      }
      onMounted(() => {
        queryEnumOptions('EhsRiskLevelEnum').then((res) => {
          // console.log('option res', res);
          if (res != undefined && res != null && res.length > 0x0) {
            const value = res[0].options.map((option) => {
              return {
                value: Number(option.key),
                label: option.value,
                color: option.attribute.split('"')[3],
              };
            });
            riskLevelOptions.value = value;
          }
        });
        // 获取风险评价的方法list
        getIdentifyMethod().then((res) => {
          methodList.value = res;
          let method = res.map((item) => {
            return {
              value: item.method,
              label: item.name,
            };
          });
          methodOption.value = method;
        });
      });
      return {
        formRef,
        register,
        registerEvaluationForm,
        hazardList,
        methodList,
        riskValueField,
        currentIndex,
        riskLevelOptions,
        validateForm,
        opSuccess,
        closeModal,
        // switchHazard,
        hazardBasicInfo,
        displayModuleTitle,
        methodOption,
        returnMarks,
        sliderTipFormatter,
        setEvaluationValue,
        getFieldsValue,
      };
    },
  });
</script>
<style scoped>
  .steps-action {
    display: flex;
    justify-content: center;
    align-items: flex-end;
    margin-top: 10px;
  }
  .steps-action Button {
    margin: 0 10px;
  }
  .ant-form-item {
    margin-bottom: 10px;
  }
  .ant-radio-button-wrapper.ant-radio-button-wrapper-checked {
    color: #000;
  }
  .ant-radio-group-solid
    .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):hover {
    color: #000;
  }
  .riskButton .ant-radio-button-wrapper:nth-child(1).ant-radio-button-wrapper-checked {
    background-color: #3caeff;
  }
  .riskButton .ant-radio-button-wrapper:nth-child(2).ant-radio-button-wrapper-checked {
    background-color: #ffef60;
  }

  .riskButton .ant-radio-button-wrapper:nth-child(3).ant-radio-button-wrapper-checked {
    background-color: orange;
  }

  .riskButton .ant-radio-button-wrapper:nth-child(4).ant-radio-button-wrapper-checked {
    background-color: rgb(253, 50, 50);
  }

  .ismajorButton .ant-radio-button-wrapper:nth-child(1).ant-radio-button-wrapper-checked {
    background-color: rgb(59, 89, 153);
    color: #fff;
    border: blue;
  }
  .ismajorButton .ant-radio-button-wrapper:nth-child(2).ant-radio-button-wrapper-checked {
    background-color: rgb(205, 32, 31);
    color: #fff;
    border: red;
  }
  .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled)::before {
    background: rgb(203, 203, 203);
  }
</style>
